package com.enki.cigarettes.utils.wechat;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.enki.cigarettes.entity.AccessTokenT;
import com.enki.cigarettes.repository.AccessTokenTRepository;
import com.enki.cigarettes.statics.StaticKeys;
import com.enki.cigarettes.utils.PrimaryKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.List;

/**
 * @author WCS.Wang
 * @version V1.0
 * @Package com.enki.cigarettes.utils.wechat
 * @Name e-cigarettes-shop-api-module
 * @Description: TODO 微信请求工具类
 * @date 2019-07-30
 */
@Component
@Slf4j
public class WechatUtil {

    @Autowired
    private WechatConfig staticWechatConfig;

    @Autowired
    private AccessTokenTRepository staticAccessTokenTRepository;

    private static WechatConfig wechatConfig;

    private static  AccessTokenTRepository accessTokenTRepository;

    @PostConstruct
    public void init() {
        wechatConfig = staticWechatConfig;
        accessTokenTRepository = staticAccessTokenTRepository;
    }


    /**
     * 发送https请求
     *
     * @param requestUrl    请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr     提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject demoJson = null;
        try {
            URL urlGet = new URL(requestUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlGet.openConnection();
            // 设置请求方式（GET/POST）
            httpURLConnection.setRequestMethod(requestMethod);
            httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.connect();
            // 当outputStr不为null时向输出流写数据
            if (outputStr != null) {
                OutputStream outputStream = httpURLConnection.getOutputStream();
                // 编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = httpURLConnection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            httpURLConnection.disconnect();
            demoJson = JSONObject.parseObject(buffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return demoJson;
    }


    /**
     * 获取ACCESS_TOKEN
     *
     * @return
     */
    public static AccessTokenT getAccessToken() {
        // 查询是否存在数据
        AccessTokenT accessToken = accessTokenTRepository.findFirstByRemoved(StaticKeys.REMOVED);
        AccessTokenT accessTokenT = null;
        if (accessToken == null) {
            String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
            String requestUrl = token_url.replace("APPID", wechatConfig.getAppid()).replace("APPSECRET", wechatConfig.getAppsecret());
            JSONObject jsonObject = WechatUtil.httpsRequest(requestUrl, "GET", null);
            if (null != jsonObject) {
                try {
                    AccessTokenT bean = new AccessTokenT();
                    bean.setId(PrimaryKey.get().toString());
                    bean.setAccessToken(jsonObject.getString("access_token"));
                    bean.setExpiresIn(jsonObject.getInteger("expires_in"));
                    bean.setCreateTime(new Date());
                    bean.setUpdateTime(new Date());
                    bean.setRemoved(false);
                    accessTokenTRepository.save(bean);
                    log.info("access_token添加成功");
                    accessTokenT = bean;
                } catch (JSONException e) {
                    // 获取token失败
                    log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
                }
            }
        } else {
            accessTokenT = accessToken;
            if (accessToken != null && ((System.currentTimeMillis() - accessToken.getUpdateTime().getTime()) / 1000) > accessToken.getExpiresIn()) {
                String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
                String requestUrl = token_url.replace("APPID",  wechatConfig.getAppid()).replace("APPSECRET", wechatConfig.getAppsecret());
                JSONObject jsonObject = WechatUtil.httpsRequest(requestUrl, "GET", null);
                if (null != jsonObject) {
                    try {
                        accessToken.setAccessToken(jsonObject.getString("access_token"));
                        accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));
                        accessToken.setUpdateTime(new Date());
                        accessTokenTRepository.save(accessToken);
                        log.info("access_token更新成功");
                        accessTokenT = accessToken;
                    } catch (JSONException e) {
                        accessToken = null;
                        // 获取token失败
                        log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
                    }
                }
            }
        }
        return accessTokenT;
    }

}
